# utils/middleware.py
import logging
import traceback
from django.http import JsonResponse
from django.core.mail import send_mail
from django.conf import settings
from django.contrib.auth.models import AnonymousUser
from utils.errors import ERROR_CODE_MAPPING  # 假设这是你定义的错误码
import inspect

logger = logging.getLogger(__name__)


class ExceptionMiddleware:
    """
    全局异常捕获中间件
    捕获视图函数中的异常并记录日志、发送邮件、返回统一错误响应
    """

    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        response = self.get_response(request)
        return response

    def process_exception(self, request, exception):
        """
        处理异常并返回自定义响应
        """
        # 捕获异常并记录详细日志
        self.log_exception(request, exception)

        # 发送邮件通知管理员（针对严重错误）
        if self.should_notify(exception):
            self.send_admin_email(request, exception)

        # 返回统一的错误响应
        return self.generate_error_response()

    def log_exception(self, request, exception):
        """
        记录异常信息，包含请求信息、异常类型、堆栈等
        """
        user = self.get_user_info(request)
        logger.error(
            f"Unhandled Exception: {exception} | User: {user} | URL: {request.path} | Params: {request.GET} | Traceback: {traceback.format_exc()}",
            exc_info=True)

    def get_user_info(self, request):
        """
        获取当前用户的信息（如果有）
        """
        if isinstance(request.user, AnonymousUser):
            return "Anonymous"
        return f"User {request.user.id} - {request.user.username}"

    def should_notify(self, exception):
        """
        判断是否需要发送邮件通知管理员
        只对系统异常进行邮件通知
        """
        # 可以根据不同的异常类型来判断是否发送邮件
        # 比如这里可以判断异常是否是系统性错误（如数据库连接失败、500 错误等）
        return isinstance(exception, Exception)  # 这里可以根据需求进行更细致的判断

    def send_admin_email(self, request, exception):
        """
        发送邮件通知管理员
        """
        subject = '系统发生异常'
        message = f"""
        错误类型: {type(exception).__name__}
        错误详情: {str(exception)}
        请求路径: {request.path}
        请求参数: {request.GET}
        用户信息: {self.get_user_info(request)}
        堆栈信息: {traceback.format_exc()}
        """
        from_email = settings.DEFAULT_FROM_EMAIL
        recipient_list = [settings.ADMIN_EMAIL]
        send_mail(subject, message, from_email, recipient_list)

    def generate_error_response(self):
        """
        返回统一的错误响应
        """
        return JsonResponse({
            "error_code": ERROR_CODE_MAPPING['99999'],
            "message": "后端服务发生异常，请联系管理员"
        }, status=500)

